package org.example.analysis.service.analyzer;

import com.github.javaparser.JavaParser;
import com.github.javaparser.ParserConfiguration;
import com.github.javaparser.ast.CompilationUnit;
import com.github.javaparser.ast.body.ClassOrInterfaceDeclaration;
import com.github.javaparser.ast.body.FieldDeclaration;
import com.github.javaparser.ast.body.MethodDeclaration;
import com.github.javaparser.ast.expr.AnnotationExpr;
import lombok.extern.slf4j.Slf4j;
import org.example.analysis.service.dataobj.ClassDataObject;
import org.example.analysis.service.dataobj.FieldDataObject;
import org.example.analysis.service.dataobj.MethodDataObject;
import org.example.analysis.service.dataobj.ParameterDataObject;

import java.io.File;
import java.io.FileInputStream;
import java.util.ArrayList;
import java.util.List;
import java.util.Optional;
import java.util.stream.Collectors;

/**
 * Java解析工具类
 */
@Slf4j
public class ClassAnalyzer {
    private static final JavaParser javaParser;
    
    static {
        ParserConfiguration config = new ParserConfiguration();
        config.setAttributeComments(true);  // 启用注释处理
        config.setLexicalPreservationEnabled(true);  // 启用词法保留
        javaParser = new JavaParser(config);
    }
    
    /**
     * 解析Java源文件
     */
    public static ClassDataObject parseJavaFile(File sourceFile) {
        try {
            log.info("解析Java文件: {}", sourceFile.getAbsolutePath());
            CompilationUnit cu = parse(sourceFile, javaParser);
            if (cu == null) {
                return null;
            }
            
            // 获取包名
            String packageName = cu.getPackageDeclaration()
                    .map(pd -> pd.getNameAsString())
                    .orElse("");
            
            // 获取类声明
            Optional<ClassOrInterfaceDeclaration> classDecl = cu.findFirst(ClassOrInterfaceDeclaration.class);
            if (!classDecl.isPresent()) {
                return null;
            }
            
            // 创建类信息对象
            ClassDataObject classInfo = new ClassDataObject();
            classInfo.setClassName(classDecl.get().getNameAsString());
            classInfo.setPackageName(packageName);
            classInfo.setFullQualifiedName(packageName + "." + classInfo.getClassName());
            
            // 设置类注释
            classInfo.setClassComment(classDecl.get().getComment()
                    .map(comment -> comment.getContent())
                    .orElse(""));
            
            // 设置父类
            if (!classDecl.get().getExtendedTypes().isEmpty()) {
                classInfo.setSuperClass(classDecl.get().getExtendedTypes().get(0).getTokenRange().toString());
            }
            
            // 设置接口列表
            classDecl.get().getImplementedTypes().forEach(type -> 
                    classInfo.getInterfaces().add(type.getNameAsString()));
            
            // 设置是否是接口和抽象类
            classInfo.setInterface(classDecl.get().isInterface());
            classInfo.setAbstract(classDecl.get().isAbstract());
            
            // 收集修饰符和注解
            List<String> modifiers = new ArrayList<>();
            // 添加访问修饰符
            if (classDecl.get().isPublic()) modifiers.add("public");
            if (classDecl.get().isPrivate()) modifiers.add("private");
            if (classDecl.get().isProtected()) modifiers.add("protected");
            if (classDecl.get().isStatic()) modifiers.add("static");
            if (classDecl.get().isFinal()) modifiers.add("final");
            // 添加注解
            classDecl.get().getAnnotations().forEach(annotation -> {
                classInfo.addAnnotaion(annotation);
                String annotationStr = "@" + annotation.getNameAsString();
                if (!annotation.getChildNodes().isEmpty()) {
                    annotationStr += "(" + annotation.getChildNodes().stream()
                            .skip(1)  // 跳过第一个节点（注解名）
                            .map(node -> node.toString())
                            .collect(Collectors.joining(", ")) + ")";
                }
                modifiers.add(annotationStr);
            });
            classInfo.setModifiers(modifiers);
            
            // 设置代码行数
            classInfo.setCodeLines(countLines(classDecl.get()));
            
            // 分析字段
            List<FieldDataObject> fields = new ArrayList<>();
            classDecl.get().getFields().forEach(field -> {
                FieldDataObject fieldInfo = parseField(field);
                if (fieldInfo != null) {
                    fields.add(fieldInfo);
                }
            });
            classInfo.setFields(fields);
            
            // 分析方法
            List<MethodDataObject> methods = new ArrayList<>();
            classDecl.get().getMethods().forEach(method -> {
                MethodDataObject methodInfo = parseMethod(method,classInfo.getClassName());
                if (methodInfo != null) {
                    methods.add(methodInfo);
                }
            });
            classInfo.setMethods(methods);
            
            // 确定类型
            classInfo.setClassType(determineClassType(classDecl.get(), methods));
            
            return classInfo;
        } catch (Exception e) {
            log.error("解析Java文件失败: {}", sourceFile.getAbsolutePath(), e);
            return null;
        }
    }
    
    /**
     * 判断类的类型
     *
     * @param classDecl 类声明
     * @param methods 方法列表
     * @return 类型（SERVICE-服务类, ENTITY-实体类, OTHER-其他）
     */
    private static String determineClassType(ClassOrInterfaceDeclaration classDecl, List<MethodDataObject> methods) {
        // 检查类名是否以特定后缀结尾
        String className = classDecl.getNameAsString();
        if (className.endsWith("Mapper")) {
            return "DAO";
        }
        if (className.endsWith("Test")) {
            return "TEST";
        }
        
        // 检查类的注解
        for (AnnotationExpr annotation : classDecl.getAnnotations()) {
            String annotationName = annotation.getNameAsString();
            // 检查Feign客户端注解
            if (annotationName.equals("FeignClient")) {
                return "CLIENT";
            }
            // 检查Controller相关注解
            if (annotationName.equals("Controller") || annotationName.equals("RestController")) {
                return "CONTROLLER";
            }
            // 检查Service相关注解
            if (annotationName.equals("Service") || annotationName.equals("Component")) {
                return "SERVICE";
            }
            // 检查Mapper注解
            if (annotationName.equals("Mapper")) {
                return "DAO";
            }
        }
        
        // 如果没有方法，认为是实体类
        if (methods == null || methods.isEmpty()) {
            return "ENTITY";
        }
        
        // 其他情况
        return "OTHER";
    }
    
    /**
     * 解析Java文件获取编译单元
     *
     * @param file Java文件
     * @param javaParser JavaParser实例
     * @return 编译单元
     */
    public static CompilationUnit parse(File file, JavaParser javaParser) {
        try (FileInputStream in = new FileInputStream(file)) {
            return javaParser.parse(in)
                    .getResult()
                    .orElse(null);
        } catch (Exception e) {
            log.error("解析Java文件失败: {}", file.getAbsolutePath(), e);
            return null;
        }
    }
    
    /**
     * 统计代码行数
     */
    private static int countLines(ClassOrInterfaceDeclaration classDecl) {
        try {
            if (classDecl.getBegin().isPresent() && classDecl.getEnd().isPresent()) {
                return classDecl.getEnd().get().line - classDecl.getBegin().get().line + 1;
            }
            return 0;
        } catch (Exception e) {
            log.error("统计代码行数失败", e);
            return 0;
        }
    }
    
    /**
     * 解析字段
     */
    private static FieldDataObject parseField(FieldDeclaration field) {
        try {
            FieldDataObject fieldInfo = new FieldDataObject();
            
            // 设置字段名和类型（取第一个变量）
            if (!field.getVariables().isEmpty()) {
                fieldInfo.setFieldName(field.getVariable(0).getNameAsString());
                fieldInfo.setFieldType(field.getVariable(0).getTypeAsString());
                // 设置默认值
                field.getVariable(0).getInitializer().ifPresent(init -> 
                    fieldInfo.setDefaultValue(init.toString()));
            }
            
            // 设置注释
            field.getComment().ifPresent(comment -> 
                fieldInfo.setFieldComment(comment.getContent()));
            
            // 设置修饰符
            List<String> modifiers = new ArrayList<>();
            field.getModifiers().forEach(modifier -> 
                modifiers.add(modifier.toString()));
            // 添加注解
            field.getAnnotations().forEach(annotation -> {
                String annotationStr = "@" + annotation.getNameAsString();
                if (!annotation.getChildNodes().isEmpty()) {
                    annotationStr += "(" + annotation.getChildNodes().stream()
                            .skip(1)
                            .map(node -> node.toString())
                            .collect(Collectors.joining(", ")) + ")";
                }
                modifiers.add(annotationStr);
            });
            fieldInfo.setModifiers(modifiers);
            
            return fieldInfo;
        } catch (Exception e) {
            log.error("解析字段失败: {}", field.toString(), e);
            return null;
        }
    }
    
    /**
     * 解析方法
     */
    public static MethodDataObject parseMethod(MethodDeclaration method,String className) {
        try {
            MethodDataObject methodInfo = new MethodDataObject();
            methodInfo.setClassName(className);
            // 设置基本信息
            methodInfo.setMethodName(method.getNameAsString());
            methodInfo.setReturnType(method.getTypeAsString());
            methodInfo.setConstructor(method.isConstructorDeclaration());
            //methodInfo.setMethodDeclaration(method);
            if(!method.getBody().isEmpty()){
                methodInfo.setMethodBody(method.getBody().get().toString());
            }
            methodInfo.setCodeLines(method.getEnd().get().line - method.getBegin().get().line + 1);
            
            // 设置注释
            method.getComment().ifPresent(comment -> 
                methodInfo.setMethodComment(comment.getContent()));
            
            // 设置修饰符
            List<String> modifiers = new ArrayList<>();
            method.getModifiers().forEach(modifier -> 
                modifiers.add(modifier.toString()));
            // 添加注解
            method.getAnnotations().forEach(annotation -> {
                 methodInfo.addAnnotation(annotation);
                String annotationStr = "@" + annotation.getNameAsString();
                if (!annotation.getChildNodes().isEmpty()) {
                    annotationStr += "(" + annotation.getChildNodes().stream()
                            .skip(1)
                            .map(node -> node.toString())
                            .collect(Collectors.joining(", ")) + ")";
                }
                modifiers.add(annotationStr);
            });
            methodInfo.setModifiers(modifiers);
            
            // 解析参数
            List<ParameterDataObject> parameters = new ArrayList<>();
            method.getParameters().forEach(param -> {
                ParameterDataObject paramInfo = new ParameterDataObject();
                paramInfo.setParameterName(param.getNameAsString());
                paramInfo.setParameterType(param.getTypeAsString());
                paramInfo.setParameterComment("");  // TODO: 从JavaDoc中提取参数注释
                parameters.add(paramInfo);
            });
            methodInfo.setParameters(parameters);
            
            return methodInfo;
        } catch (Exception e) {
            log.error("解析方法失败: {}", method.toString(), e);
            return null;
        }
    }
} 